﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Diagnostics;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace AzukiMapUI
{
    public class AzukiWindow : ContentControl
    {
        public delegate void MyWindowClosedHandler(object sender, EventArgs e);
        public event MyWindowClosedHandler MyWindowClosed;

        string title = "No title";
        string headerIconSrc = "./icons/application.png";

        TextBlock windowTitle;
        UIElement closeButton;
        UIElement headerRect;
        Image headerIcon;
        Grid windowRoot;
        TranslateTransform windowTransform;

        bool isMovable = true;
        bool isMoving = false;
        bool hasCloseButton = true;

        Point mouseOrigin;

        const string closeButtonName = "closeButton";
        const string windowTitleName = "windowTitle";
        const string headerIconName = "headerIcon";
        const string headerRectName = "headerRect";
        const string windowRootName = "windowRoot";

        public string Title
        {
            get { return title; }
            set 
            { 
                title = value;
                if (IsEnabled)
                {
                    changeTitle();
                }
            }
        }

        public string HeaderIconSrc
        {
            get { return headerIconSrc; }
            set
            {
                headerIconSrc = value;
                if (IsEnabled)
                {
                    changeHeaderIcon();
                }
            }
        }

        public bool HasCloseButton
        {
            get { return hasCloseButton; }
            set
            {
                hasCloseButton = value;
                if (IsEnabled)
                {
                    changeCloseButton();
                }
            }
        }

        protected virtual void OnMyWindowClosed(EventArgs e)
        {
            if (MyWindowClosed != null)
            {
                MyWindowClosed(this, e);
            }
        }

        public AzukiWindow()
        {
            DefaultStyleKey = typeof(AzukiWindow);
            mouseOrigin = new Point();
            windowTransform = new TranslateTransform();
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            windowTitle = (TextBlock)GetTemplateChild(windowTitleName);
            windowRoot = (Grid)GetTemplateChild(windowRootName);
            headerIcon = (Image)GetTemplateChild(headerIconName);
            headerRect = (UIElement)GetTemplateChild(headerRectName);
            closeButton = (UIElement)GetTemplateChild(closeButtonName);
            
            // set mouse events
            headerRect.MouseLeftButtonDown += new MouseButtonEventHandler(headerRect_MouseLeftButtonDown);
            headerRect.MouseMove += new MouseEventHandler(headerRect_MouseMove);
            headerRect.MouseLeftButtonUp += new MouseButtonEventHandler(headerRect_MouseLeftButtonUp);
            headerIcon.MouseLeftButtonDown += new MouseButtonEventHandler(headerRect_MouseLeftButtonDown);
            headerIcon.MouseMove += new MouseEventHandler(headerRect_MouseMove);
            headerIcon.MouseLeftButtonUp += new MouseButtonEventHandler(headerRect_MouseLeftButtonUp);
            windowTitle.MouseLeftButtonDown += new MouseButtonEventHandler(headerRect_MouseLeftButtonDown);
            windowTitle.MouseMove += new MouseEventHandler(headerRect_MouseMove);
            windowTitle.MouseLeftButtonUp += new MouseButtonEventHandler(headerRect_MouseLeftButtonUp);
            closeButton.MouseLeftButtonDown += new MouseButtonEventHandler(CloseButtonMouseDown);

            changeTitle();
            changeHeaderIcon();
            changeCloseButton();
        }

        void CloseButtonMouseDown(object sender, MouseButtonEventArgs e)
        {
            Close();
        }

        void headerRect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (isMovable)
            {
                isMoving = true;
                UIElement parentElement = (UIElement)Parent;
                if (parentElement != null)
                {
                    mouseOrigin = e.GetPosition(parentElement);
                    // set last transform values
                    mouseOrigin.X -= windowTransform.X;
                    mouseOrigin.Y -= windowTransform.Y;
                    // set events on parent also.
                    addMoveEventOnParent();
                }
            }
        }

        void headerRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isMoving = false;
            removeMoveEventOnParent();
        }

        void headerRect_MouseLeave(object sender, MouseEventArgs e)
        {
            //_isMoving = false;
        }

        void headerRect_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMoving)
            {
                UIElement parentElement = (UIElement)Parent;
                Point currentPosition;
                if (parentElement != null)
                {
                    currentPosition = e.GetPosition(parentElement);
                    windowTransform.X = currentPosition.X - mouseOrigin.X;
                    windowTransform.Y = currentPosition.Y - mouseOrigin.Y;
                    MoveWindow();
                }
            }
        }

        void addMoveEventOnParent()
        {
            UIElement parentElement = (UIElement)Parent;
            parentElement.MouseMove += new MouseEventHandler(headerRect_MouseMove);
        }

        void removeMoveEventOnParent()
        {
            UIElement parentElement = (UIElement)Parent;
            parentElement.MouseMove -= new MouseEventHandler(headerRect_MouseMove);
        }

        void changeTitle()
        {
            windowTitle.Text = title;
        }

        void changeHeaderIcon()
        {
            Uri iconUri = new Uri(headerIconSrc, UriKind.Relative);
            ImageSource icon = new BitmapImage(iconUri);
            headerIcon.Source = icon;
        }

        private void changeCloseButton()
        {
            if (hasCloseButton)
            {
                closeButton.Visibility = Visibility.Visible;
            }
            else
            {
                closeButton.Visibility = Visibility.Collapsed;
            }
        }

        void MoveWindow()
        {
            RenderTransform = windowTransform;
        }

        public void Close()
        {
            try
            {
                Panel parentElement = (Panel)Parent;
                parentElement.Children.Remove(this);
                EventArgs ea = new EventArgs();
                OnMyWindowClosed(ea);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

    }
}
